(()=>{
	let sqlite = null;
	let lastSqlError = null;
	let dbFilePath = null;

	window.Model = class Model extends Data {
		static get table() {return ""};
		static get primary() {return "id"};
		
		constructor() {
			super();
			
			this._isload = false;
			this._sql = null;
			
			this._ok = false;
			this._lastResult = null;
			this._error = '';
		}
		
		static run(sql, params) {
			let result = this.getSqliteDb().run(sql, params);
			let returnData = {sql:this.getSqliteDb().sql};
			
			if(result && result.error) {
				lastSqlError = result.error;
				returnData.error = result;
				Log.addLine('SQL ERROR:' + JSON.stringify(result));
			} else {
				lastSqlError = null;
				returnData.error = false;
				returnData.data = result;
				Log.addLine('RUN SQL:' + returnData.sql);
			}
			
			return returnData;
		}

		static getAllTable() {
			let result = Model.run(`SELECT * FROM SQLITE_MASTER WHERE type='table'`);
			
			if(result.error) {
				return [];
			} else {
				return result.data;
			}
		}

		get id() {
			return this.getId();
		}
		
		set id(id) {
			this.setId(id);
		}
		
		setId(id) {
			this._data[this.constructor.primary] = id;
			return this;
		}
		
		getId() {
			return this._data[this.constructor.primary];
		}
		
		collector() {
			return eval(`new ${this.constructor.name}Collector;`);
		};
		
		getError() {
			return this._error;
		}
		
		static getCollector() {
			return (new this.constructor()).collector();
		}
		
		/**
		 * 从数据库中加载数据
		 * @param id
		 * @param fieldName
		 * @returns {Window.Model}
		 */
		load(id, fieldName) {
			if(!id && this._isload) {
				return this;
			}
			
			let field = fieldName ? fieldName : this.constructor.primary;
			id = id ? id : this.id;
			
			let result = Model.run(`SELECT * FROM "${this.constructor.table}" WHERE "${field}"=?`, [id]);
			
			if(result.error) {
				this._error = result.error;
				this._isload = false;
				this._ok = false;
				this.setId(null);
				
			} else {
				this._isload = true;
				this._error = null;
				this._ok = true;
				
				if(result.data.length == 0) {
					this._data = {};
				} else {
					this._data = result.data[0];
				}
			}
			
			this._sql = this.constructor.getLastSql();
			return this;
		}
		
		delete() {
			let sql = `DELETE FROM ${this.constructor.table} WHERE ${this.constructor.primary}='${this.id}'`;
			let result = Model.run(sql);
			
			if(result.error) {
				this._ok = false;
				lastSqlError = result.error;
			} else {
				this._ok = true;
				lastSqlError = null;
			}
			
			return this;
		}
		
		/**
		 *  保存模型数据
		 * @returns {Window.Model}
		 */
		save() {
			if(this.id) {
				let cond = {};
				cond [this.constructor.primary] = this.id;
				
				let data = JSON.parse(JSON.stringify(this._modifyData));

				for(let i in data) {
					data[i] = this.constructor.escapeValue(data[i]);
				}
				
				this._lastResult = this.getDb().update(this.constructor.table, data, cond, res => {
					if(res.error) {
						this._ok = false;
						this._error = res.error;
						lastSqlError = res.error;
					} else {
						this._ok = true;
						this._error = null;
						lastSqlError = null;
					}
				});
				this._sql = this.constructor.getLastSql();
				Log.addLine('RUN SQL:' + this._sql);
				
			} else {
				let data = this.get();
				
				for(let i in data) {
					data[i] = this.constructor.escapeValue(data[i]);
				}
				
				try {
					delete data[this.constructor.primary];
				} catch (e) {}
				
				let elm = this;
				
				this.getDb().insert(this.constructor.table, data, res => {
					if(res.error) {
						this._ok = false;
						lastSqlError = res.error;
						this._error = res.error;
					} else {
						elm.id = res;
						elm._lastResult = res;
						this._ok = true;
						lastSqlError = null;
						this._error = null;
					}
				});
				this._sql = this.constructor.getLastSql();
				Log.addLine('RUN SQL:' + this._sql);
			}
			
			return this;
		}
		
		ok() {
			return this._ok;
		}
		
		getLastResult() {
			return this._lastResult;
		}
		
		getSql() {
			return this._sql;
		}
		
		static getLastError() {
			return lastSqlError;
		}
		
		static getLastSql() {
			return this.getSqliteDb().getSql();
		}
		
		getDb() {
			return this.constructor.getSqliteDb();
		}
		
		static getSqliteDb() {
			if(sqlite) {
				return sqlite;
			}
			
			sqlite = initSqlite();
			return sqlite;
		}
		
		static getDbFilePath() {
			return getDbFilePath();
		}
		
		static escapeValue(value) {
			if(!Core.isString(value)) {
				return value;
			}
			
			return String(value)
				// .replace(/\n/g, '\\n')
				.replace(/'/g,  "''")
			;
		}
 	};

	function initSqlite() {
		let verbose = nw.require('sqlite-sync');
		verbose.connect(getDbFilePath());
		return verbose;
	}
	
	function getDbFilePath() {
		if(!dbFilePath) {
			let fs = nw.require('fs');
			let baseDir = Core.getBaseDir();
			
			let fileName = COREVAR.MANIFEST.dbname;
			fileName = fileName ? fiileName : nw.App.manifest.name;
			let dbfileDir = `${baseDir}/data`;
			
			if(!fs.existsSync(dbfileDir)) {
				fs.mkdirSync(dbfileDir);
			}
			
			dbFilePath = `${dbfileDir}/${fileName}.db`;
			Log.addLine(`数据文件:${dbFilePath}`);
		}
		
		return dbFilePath;
	}
	
	Core.setToParentWindow('Model', Model);
})();